//
//  PrivacyPermissionManager.m
//  Tools
//
//  Created by han on 2019/1/22.
//  Copyright © 2019 han. All rights reserved.
//

#import "PrivacyPermissionManager.h"

#import <Photos/Photos.h>
#import <AVFoundation/AVFoundation.h>
#import <AddressBook/AddressBook.h>
#import <Contacts/Contacts.h>
#import <UserNotifications/UserNotifications.h>
#import <CoreLocation/CoreLocation.h>

static PrivacyPermissionManager *_instance = nil;
static NSInteger const PrivacyPermissionTypeLocationDistanceFilter = 10;
@interface PrivacyPermissionManager()

@property (strong,nonatomic) CLLocationManager * locationManager;

@end
@implementation PrivacyPermissionManager
#pragma clang diagnostic push
#pragma clang diagnostic ignored"-Wdeprecated-declarations"

+ (instancetype)shareManager {
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        _instance = [[self alloc] init];
    });
    return _instance;
}
- (instancetype)init
{
    self = [super init];
    if (self) {
        self.locationManager = [[CLLocationManager alloc]init];
    }
    return self;
}
+ (instancetype)allocWithZone:(struct _NSZone *)zone {
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        _instance = [super allocWithZone:zone];
    });
    return _instance;
}

- (id)copyWithZone:(nullable NSZone *)zone {
    return _instance;
}

- (void)accessPrivacyPermissionWithType:(PrivacyPermissionType)permissionType completion:(void (^)(BOOL response, PrivacyPermissionAuthorizationStatus))completion {
    switch (permissionType) {
        case PrivacyPermissionTypePhoto: // 相册
        {
            // 默认在用户选择权限之后，再次请求权限，不再弹出提示框
            [PHPhotoLibrary requestAuthorization:^(PHAuthorizationStatus status) {
                //回调线程不一定在主线程
                if (status == PHAuthorizationStatusAuthorized) {
                    completion(YES,PrivacyPermissionAuthorizationStatusAuthorized);
                } else if (status == PHAuthorizationStatusDenied) {
                    completion(NO,PrivacyPermissionAuthorizationStatusDenied);
                } else if (status == PHAuthorizationStatusNotDetermined) {
                    completion(NO,PrivacyPermissionAuthorizationStatusNotDetermined);
                } else if (status == PHAuthorizationStatusRestricted) {
                    completion(NO,PrivacyPermissionAuthorizationStatusRestricted);
                }
            }];
        }
            break;
        case PrivacyPermissionTypeContact:
        {
            if (@available(iOS 9.0, *)) {
                CNContactStore *contactStore = [[CNContactStore alloc] init];
                [contactStore requestAccessForEntityType:CNEntityTypeContacts completionHandler:^(BOOL granted, NSError * _Nullable error) {
                    CNAuthorizationStatus status = [CNContactStore authorizationStatusForEntityType:CNEntityTypeContacts];
                    if (granted) {
                        completion(YES,PrivacyPermissionAuthorizationStatusAuthorized);
                    } else {
                        if (status == CNAuthorizationStatusDenied) {
                            completion(NO,PrivacyPermissionAuthorizationStatusDenied);
                        }else if (status == CNAuthorizationStatusRestricted){
                            completion(NO,PrivacyPermissionAuthorizationStatusRestricted);
                        }else if (status == CNAuthorizationStatusNotDetermined){
                            completion(NO,PrivacyPermissionAuthorizationStatusNotDetermined);
                        }
                    }
                    
                }];
            }else{
                
                ABAddressBookRef addressBook =   ABAddressBookCreateWithOptions(NULL, NULL);
                ABAddressBookRequestAccessWithCompletion(addressBook, ^(bool granted, CFErrorRef error) {
                    ABAuthorizationStatus status = ABAddressBookGetAuthorizationStatus();
                    if (granted) {
                        completion(YES,PrivacyPermissionAuthorizationStatusAuthorized);
                    }else{
                        if (status == kABAuthorizationStatusDenied) {
                            completion(NO,PrivacyPermissionAuthorizationStatusDenied);
                        }else if (status == kABAuthorizationStatusNotDetermined){
                            completion(NO,PrivacyPermissionAuthorizationStatusNotDetermined);
                        }else if (status == kABAuthorizationStatusRestricted){
                            completion(NO,PrivacyPermissionAuthorizationStatusRestricted);
                        }
                    }
                    
                });
            }
        }
            break;
        case PrivacyPermissionTypeCamera:
        {
            [AVCaptureDevice requestAccessForMediaType:AVMediaTypeVideo completionHandler:^(BOOL granted) {
                AVAuthorizationStatus status = [AVCaptureDevice authorizationStatusForMediaType:AVMediaTypeVideo];
                if (granted) {
                    completion(YES,PrivacyPermissionAuthorizationStatusAuthorized);
                } else {
                    if (status == AVAuthorizationStatusDenied) {
                        completion(NO,PrivacyPermissionAuthorizationStatusDenied);
                        
                    } else if (status == AVAuthorizationStatusNotDetermined) {
                        completion(NO,PrivacyPermissionAuthorizationStatusNotDetermined);
                    } else if (status == AVAuthorizationStatusRestricted) {
                        completion(NO,PrivacyPermissionAuthorizationStatusRestricted);
                    }
                }
                
            }];
        }
            break;
        case PrivacyPermissionTypeMicrophone:
        {
            [AVCaptureDevice requestAccessForMediaType:AVMediaTypeAudio completionHandler:^(BOOL granted) {
                AVAuthorizationStatus status = [AVCaptureDevice authorizationStatusForMediaType:AVMediaTypeVideo];
                
                if (granted) {
                    completion(YES,PrivacyPermissionAuthorizationStatusAuthorized);
                } else {
                    if (status == AVAuthorizationStatusDenied) {
                        completion(NO,PrivacyPermissionAuthorizationStatusDenied);
                        
                    } else if (status == AVAuthorizationStatusNotDetermined) {
                        completion(NO,PrivacyPermissionAuthorizationStatusNotDetermined);
                    } else if (status == AVAuthorizationStatusRestricted) {
                        completion(NO,PrivacyPermissionAuthorizationStatusRestricted);
                    }
                }
                
            }];
        }
            break;
        case PrivacyPermissionTypeLocation:
        {
            if ([CLLocationManager locationServicesEnabled]) {
                 CLAuthorizationStatus status = [CLLocationManager authorizationStatus];
                if (status == kCLAuthorizationStatusNotDetermined){
                    CLLocationManager *locationManager = self.locationManager;
                    [locationManager requestAlwaysAuthorization];
                    [locationManager requestWhenInUseAuthorization];
                    locationManager.desiredAccuracy = kCLLocationAccuracyBestForNavigation;
                    locationManager.distanceFilter = PrivacyPermissionTypeLocationDistanceFilter;
                    [locationManager startUpdatingLocation];
                    // 不能获取到用户的选择
                    CLAuthorizationStatus stas = [CLLocationManager authorizationStatus];
                    [self completionWithLocationStatus:stas completion:completion];
                    
                }else{
                    [self completionWithLocationStatus:status completion:completion];
                }
            }else {// 总定位服务未开启
                 completion(NO,PrivacyPermissionAuthorizationStatusLocationDisable);
            }
        }
            break;
        case PrivacyPermissionTypePushNotification:
        {
            if (@available(iOS 10.0, *)) {
                UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter];
                UNAuthorizationOptions types=UNAuthorizationOptionBadge|UNAuthorizationOptionAlert|UNAuthorizationOptionSound;
                [center requestAuthorizationWithOptions:types completionHandler:^(BOOL granted, NSError * _Nullable error) {
                    if (granted) {
                        [center getNotificationSettingsWithCompletionHandler:^(UNNotificationSettings * _Nonnull settings) {
                            
                        }];
                    } else {
                        [[UIApplication sharedApplication]openURL:[NSURL URLWithString:UIApplicationOpenSettingsURLString] options:@{UIApplicationOpenURLOptionUniversalLinksOnly:@""} completionHandler:^(BOOL success) { }];
                    }
                }];
            } else {
                [[UIApplication sharedApplication] registerUserNotificationSettings:[UIUserNotificationSettings settingsForTypes:UIUserNotificationTypeAlert | UIUserNotificationTypeSound | UIUserNotificationTypeBadge categories:nil]];

            }
        }
            break;
        default:
            break;
    }
}

/*
 * 默认在用户选择权限之后，再次请求权限，不再弹出提示框
 相册权限：
 iOS11之前：访问相册和存储照片到相册（读写权限），需要用户授权，需要添加NSPhotoLibraryUsageDescription。
 iOS11之后：默认开启访问相册权限（读权限），无需用户授权，无需添加NSPhotoLibraryUsageDescription，适配iOS11之前的还是需要加的。添加图片到相册（写权限），需要用户授权，需要添加NSPhotoLibraryAddUsageDescription。
 */
#pragma mark --- private

- (void)completionWithLocationStatus:(CLAuthorizationStatus)status completion:(void (^)(BOOL, PrivacyPermissionAuthorizationStatus))completion{
    if (status == kCLAuthorizationStatusAuthorizedAlways) {
        completion(YES,PrivacyPermissionAuthorizationStatusLocationAlways);
    } else if (status == kCLAuthorizationStatusAuthorizedWhenInUse) {
        completion(YES,PrivacyPermissionAuthorizationStatusLocationWhenInUse);
    } else if (status == kCLAuthorizationStatusDenied) {
        completion(NO,PrivacyPermissionAuthorizationStatusDenied);
    } else if (status == kCLAuthorizationStatusNotDetermined) {
        completion(NO,PrivacyPermissionAuthorizationStatusNotDetermined);
    } else if (status == kCLAuthorizationStatusRestricted) {
        completion(NO,PrivacyPermissionAuthorizationStatusRestricted);
    }
}

+ (void)jumpSetting{
    if ( @available(iOS 10.0, *)){
        [[UIApplication sharedApplication]openURL:[NSURL URLWithString:UIApplicationOpenSettingsURLString] options:@{} completionHandler:nil];
    } else {
        [[UIApplication sharedApplication]openURL:[NSURL URLWithString:UIApplicationOpenSettingsURLString]];
    }
}
+ (BOOL)isCameraAvaliable {
#if TARGET_IPHONE_SIMULATOR
    return NO;
#else
    if ([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera]) {
        return YES;
    }
    return NO;
#endif
}
@end
#pragma clang diagnostic pop
